import 'dart:async';

import 'package:ad_common/third_ad.dart';
import 'package:ad_common/third_ad_instance.dart';
import 'package:ad_common/util/log.dart';
import 'package:anythink_sdk/at_interstitial.dart';
import 'package:anythink_sdk/at_interstitial_response.dart';
import 'package:anythink_sdk/at_listener.dart';
import 'package:top_on_ad_plugin/top_on_base_ad.dart';

/// FileName top_on_insert_video_ad
/// @Author zhuqingfang
/// @Date 2022/9/30 2:19 下午
/// @Description top on insert video ad
//ad request map
Map<String, TopOnInsertAd> _insertAdRequest = {};

//ad loaded map
Map<String, TopOnInsertAd> _insertAdLoaded = {};

//ad show object
TopOnInsertAd? _insertAdShow;
//为空初始化，不空，不初始化，确保listener只注册一次
StreamSubscription? _initInsertAdListener;

class TopOnInsertAd extends TopOnBaseAd {
  TopOnInsertAd({required ThirdAdParams thirdAdParams})
      : super(thirdAdParams: thirdAdParams);

  @override
  void load() {
    //在父类执行top on sdk 初始化
    super.load();

    //注册监听回调，只初始化一次
    _initInsertAdListener = _initInsertAdListener ?? _insertAdListener();

    //检查广告状态，如果广告正在加载中或者placementId对应的广告已经准备好，不执行加载,否则加载广告
    checkAdState(
        thirdAdType: ThirdAdType.topOnInsertAd,
        placementId: thirdAdParams.placementId,
        isLoaded: (isLoaded) {
          if (isLoaded == true) {
            //如果对应的placement有缓存广告，不再请求广告
            thirdAdParams.thirdAdEventCallback(
                AdCallbackEvent.loadFail,
                '${thirdAdParams.placementId} top on insert ad is loading',
                {thirdAdParams.placementId: 'isLoading'});
          } else {
            //一个 placementId 对应一个实例，缓存起来
            _insertAdRequest[thirdAdParams.placementId] = this;

            //请求广告
            _loadInterstitialAd(placementId: thirdAdParams.placementId);
          }
        });
  }

  @override
  void show() {
    //是否可以展示广告
    isShowTopOnAd(
        thirdAdType: ThirdAdType.topOnInsertAd,
        placementId: thirdAdParams.placementId,
        isShowAd: (isShowAd) {
          //可展示
          if (isShowAd == true) {
            if (_insertAdLoaded.containsKey(thirdAdParams.placementId)) {
              _insertAdShow = _insertAdLoaded[thirdAdParams.placementId];
            }
            if (thirdAdParams.thirdAdExtraInputParam != null) {
              Log.i(
                  'top on show sceneId:${thirdAdParams.thirdAdExtraInputParam as String}');
            }
            //展示
            _showInsertAd(
                placementId: thirdAdParams.placementId,
                sceneId: thirdAdParams.thirdAdExtraInputParam as String?);
          } else {
            //没有广告可展示
            Map<String, Object> infoMap = {
              thirdAdParams.placementId: 'notReady'
            };
            thirdAdParams.thirdAdEventCallback(
                AdCallbackEvent.showFail,
                '${thirdAdParams.placementId} top on insert ad is notReady',
                infoMap);
          }
        });
  }
}

//展示插屏广告
_showInsertAd({required String placementId, String? sceneId}) {
  if (sceneId?.isNotEmpty == true) {
    ATInterstitialManager.showSceneInterstitialAd(
        placementID: placementId, sceneID: sceneId!);
  } else {
    ATInterstitialManager.showInterstitialAd(
      placementID: placementId,
    );
  }
}

//请求插屏广告
void _loadInterstitialAd({required String placementId}) {
  ATInterstitialManager.loadInterstitialAd(
      placementID: placementId, extraMap: {});
}

//获取所有插屏广告缓存信息，目前仅供测试看日志用
_getInterstitialValidAds({required String placementId}) {
  ATInterstitialManager.getInterstitialValidAds(placementID: placementId).then(
      (value) =>
          Log.i('insert video ad $placementId all available ad info:$value'));
}

//检查已缓存广告的状态信息
_checkAdStatus({required String placementId}) {
  return ATInterstitialManager.checkInterstitialLoadStatus(
    placementID: placementId,
  );
}

//注册监听回调
StreamSubscription _insertAdListener() {
  return ATListenerManager.interstitialEventHandler.listen((value) async {
    switch (value.interstatus) {
      //广告加载失败
      case InterstitialStatus.interstitialAdFailToLoadAD:
        Log.i(
            "flutter interstitialAdFailToLoadAD ---- placementID: ${value.placementID} ---- errStr:${value.requestMessage}");
        if (_insertAdRequest.containsKey(value.placementID)) {
          Map<String, Object> infoMap = {value.placementID: 'loadFail'};
          _insertAdRequest[value.placementID]?.thirdAdParams.thirdAdEventCallback(
              AdCallbackEvent.loadFail,
              'top on insert ad placementID :${value.placementID} load fail errStr:${value.requestMessage}',
              infoMap);
        }
        break;
      //广告加载成功
      case InterstitialStatus.interstitialAdDidFinishLoading:
        Log.i(
            "flutter interstitialAdDidFinishLoading ---- placementID: ${value.placementID}");
        if (_insertAdRequest.containsKey(value.placementID)) {
          _insertAdLoaded[value.placementID] =
              _insertAdRequest[value.placementID]!;
          final adState = await _checkAdStatus(placementId: value.placementID);
          Log.i(
              'flutter insertAdDidFinishLoading adInfo:${adState["adInfo"].toString()}');
          _insertAdLoaded[value.placementID]
              ?.thirdAdParams
              .thirdAdEventCallback(
                  AdCallbackEvent.loadSuccess,
                  'top on insert ad placementID:${value.placementID}  loaded',
                  adState['adInfo']);
        }
        //获取所有缓存广告信息，目前只供测试看日志用
        _getInterstitialValidAds(placementId: value.placementID);
        break;
      //广告视频开始播放，部分平台有此回调
      case InterstitialStatus.interstitialAdDidStartPlaying:
        Log.i(
            "flutter interstitialAdDidStartPlaying ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _insertAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onShow,
            'top on insert ad placementID:${value.placementID}  onShow',
            value.extraMap);
        break;
      //广告视频播放结束，部分广告平台有此回调
      case InterstitialStatus.interstitialAdDidEndPlaying:
        Log.i(
            "flutter interstitialAdDidEndPlaying ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告视频播放失败，部分广告平台有此回调
      case InterstitialStatus.interstitialDidFailToPlayVideo:
        Log.i(
            "flutter interstitialDidFailToPlayVideo ---- placementID: ${value.placementID} ---- errStr:${value.requestMessage}");
        break;
      //广告展示成功
      case InterstitialStatus.interstitialDidShowSucceed:
        Log.i(
            "flutter interstitialDidShowSucceed ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _insertAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onShow,
            'top on insert ad placementID:${value.placementID}  onShow',
            value.extraMap);
        break;
      //广告展示失败
      case InterstitialStatus.interstitialFailedToShow:
        Log.i(
            "flutter interstitialFailedToShow ---- placementID: ${value.placementID} ---- errStr:${value.requestMessage}");
        _insertAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.showFail,
            'top on insert ad placementID:${value.placementID}  onShow fail',
            value.extraMap);
        break;
      //广告被点击
      case InterstitialStatus.interstitialAdDidClick:
        Log.i(
            "flutter interstitialAdDidClick ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _insertAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onClick,
            'top on insert ad placementID:${value.placementID}  onClick',
            value.extraMap);
        break;
      //Deeplink
      case InterstitialStatus.interstitialAdDidDeepLink:
        Log.i(
            "flutter interstitialAdDidDeepLink ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告被关闭
      case InterstitialStatus.interstitialAdDidClose:
        Log.i(
            "flutter interstitialAdDidClose ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _insertAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onClose,
            'top on insert ad placementID:${value.placementID}  onDismiss',
            value.extraMap);
        break;
      case InterstitialStatus.interstitialUnknown:
        Log.i("flutter interstitialUnknown");
        break;
    }
  });
}
